package com.dareway.juc.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class reentrantLock {
    public static void main(String[] args) throws InterruptedException {
//        公平锁：多个线程按照申请锁的顺序去获得锁，线程会直接进入队列去排队，永远都是队列的第一位才能得到锁。
//        非公平锁：多个线程去获取锁的时候，会直接去尝试获取，获取不到，再去进入等待队列，如果能获取到，就直接获取到锁。
        ReentrantLock lock = new ReentrantLock(true); // 是否为公平锁
        Condition condition = lock.newCondition();
        lock.lock();
        lock.lock();   //连续加锁2次
        new Thread(() -> {
            System.out.println("线程2想要获取锁");
            lock.lock();
            System.out.println("线程2成功获取到锁");
            System.out.println("线程2当前加锁次数："+lock.getHoldCount()+"，是否被锁："+lock.isLocked());
            lock.unlock();
        }).start();
        System.out.println("线程1当前加锁次数："+lock.getHoldCount()+"，是否被锁："+lock.isLocked());
        System.out.println("当前等待锁释放的线程数："+lock.getQueueLength());
        lock.unlock();
        System.out.println("线程1释放了一次锁");
        TimeUnit.SECONDS.sleep(1);
        System.out.println("线程1当前加锁次数："+lock.getHoldCount()+"，是否被锁："+lock.isLocked());
        System.out.println("当前等待锁释放的线程数："+lock.getQueueLength());
        System.out.println("当前Condition的等待线程数："+lock.getWaitQueueLength(condition));
        lock.unlock();
        System.out.println("线程1再次释放了一次锁");  //释放两次后其他线程才能加锁

        System.out.println(">>>>>>>>>>>>>>公平锁>>>>>>>>>>>>>>");


        Runnable action = () -> {
            System.out.println("线程 "+Thread.currentThread().getName()+" 开始获取锁...");
            lock.lock();
            System.out.println("线程 "+Thread.currentThread().getName()+" 成功获取锁！");
            lock.unlock();
        };
        for (int i = 0; i < 10; i++) {   //建立10个线程
            new Thread(action, "T"+i).start();
        }
    }
}
